package com.imagination.applet.controller.web.configuration;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.imagination.applet.domain.support.authentication.modal.WechatToken;
import com.imagination.applet.domain.support.authentication.service.LoginService;
import com.imagination.applet.domain.user.model.User;
import com.imagination.applet.domain.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class WeChatAuthenticationProvider implements AuthenticationProvider {

    private final LoginService loginService;
    private final UserService userService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        WeChatAuthenticationToken weChat = (WeChatAuthenticationToken)authentication.getDetails();
        WechatToken token = null;
        try {
            token = loginService.auth(weChat.getCode());
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        Optional<User> user = userService.getUserByOpenId(token.getOpenId());
        User u = user.orElse(null);
        if (user.isEmpty()) {
            u = userService.createUser(token.getOpenId(), "wx", weChat.getShareCode());
        }
        return buildToken(u.getId(), u.getOpenId(), u.getOpenIdType(), token.getSessionKey());
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return WeChatAuthenticationToken.class.isAssignableFrom(authentication);
    }

    private JwtToken buildToken(Long userId, String openId, String openType, String accessKey) {
        return new JwtToken(userId, openId, openType, accessKey);
    }

}
